package main

import (
	"encoding/base64"
	"encoding/json"
	"fmt"
	"reflect"
)

const (
	decodeFieldNameTag = "dfn"
)

type Student struct {
	NameByte []byte
	Name string `json:"name" dfn:"NameByte"`
}

func main() {
	//s := &Student{Name: base64.StdEncoding.EncodeToString([]byte("咖啡色的羊驼"))}

	s := &Student{}
	json.Unmarshal([]byte("{\"name\":\"5ZKW5ZWh6Imy55qE576K6am8\"}"), s)

	v := reflect.ValueOf(s)

	t := reflect.TypeOf(*s)

	// the value must be pointer type, or it would not be modified.
	if v.Kind() != reflect.Ptr {
		fmt.Println("not a ptr type, can not modify the value")
		return
	}

	// get the element of the pointer
	v = v.Elem()

	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		// found the field with tag.
		if field.Tag != "" {
			// if the dfn tag is specified.
			decodeFieldName := field.Tag.Get(decodeFieldNameTag)
			fmt.Println(decodeFieldName)
			decodeField := v.FieldByName(decodeFieldName)
			fmt.Println(decodeField.Kind())

			// decode field must be a slice kind.
			if decodeField.Kind() == reflect.Slice {
				// decode the value of field with dfn tag.
				decodeBytes, err := base64.StdEncoding.DecodeString(v.Field(i).String())
				if err != nil {
					fmt.Println(err)
					return
				}

				// set the decode field with the decode value.
				decodeField.SetBytes(decodeBytes)
			}
		}
	}

	fmt.Printf("%#v \n", *s)
	fmt.Println(string(s.NameByte))

	// 如果是整型的话
	// test := 888
	// testV := reflect.ValueOf(&test)
	// testV.Elem().SetInt(666)
	// fmt.Println(test)
}